/// @tags: EdgeDiv Div
#include <algorithm>
#include <cctype>
#include <cstdio>

const int N = 1e5 + 5, M = 2e5 + 5, inf = 0x3f3f3f3f;

template <typename T>
inline T &read(T &x) {
  x = 0;
  bool f = false;
  short ch = getchar();
  while (!isdigit(ch)) {
    if (ch == '-') f = true;
    ch = getchar();
  }
  while (isdigit(ch)) x = x * 10 + (ch ^ '0'), ch = getchar();
  if (f) x = -x;
  return x;
}

struct Graph {
  int e_cnt = 1, heads[N];

  struct Edge {
    int v, nxt, w;
  };
  Edge e[N << 1];

  inline void add(int u, int v, int w) {
    e[++e_cnt].v = v, e[e_cnt].nxt = heads[u], heads[u] = e_cnt, e[e_cnt].w = w;
    e[++e_cnt].v = u, e[e_cnt].nxt = heads[v], heads[v] = e_cnt, e[e_cnt].w = w;
  }
} E, G;

struct Path {
  int min, len;
  Path() {}
  Path(int min, int len) : min(min), len(len) {}
  inline bool operator<(const Path &rhs) const { return min < rhs.min; }
} path[2][N];

int n, tot, sums, rt, mn;
int ffa[N], siz[N], val[N], cnt[2];
bool del[N];
long long ans;

inline void insert(int u, int v) {
  G.add(++tot, v, 1);
  val[tot] = val[ffa[u]];
  G.add(ffa[u], tot, 0);
  ffa[u] = tot;
}

void build(int u, int fa) {
  for (int i = E.heads[u], v; i; i = E.e[i].nxt)
    if ((v = E.e[i].v) != fa) insert(u, v), build(v, u);
}

void getRoot(int u, int fa) {
  siz[u] = 1;
  for (int i = G.heads[u], v; i; i = G.e[i].nxt)
    if (!del[i >> 1] && (v = G.e[i].v) != fa) {
      getRoot(v, u);
      siz[u] += siz[v];
      int tmp = std::max(siz[v], sums - siz[v]);
      if (mn > tmp) mn = tmp, rt = i;
    }
}

void dfs(int u, int fa, int len, int min, const bool typ) {
  min = std::min(val[u], min);
  path[typ][++cnt[typ]] = Path(min, len);
  for (int i = G.heads[u], v; i; i = G.e[i].nxt)
    if (!del[i >> 1] && (v = G.e[i].v) != fa) dfs(v, u, len + G.e[i].w, min, typ);
}

inline void calc(const bool typ, int w) {
  Path *const f = path[typ], *const g = path[!typ];
  for (int i = cnt[typ], j = cnt[!typ], maxlen = 0; i; --i) {
    for (; j && g[j].min >= f[i].min;) maxlen = std::max(maxlen, g[j--].len);
    if (j < cnt[!typ]) ans = std::max(ans, 1ll * (maxlen + f[i].len + w + 1) * f[i].min);
  }
}

void solve(int u, int pres) {
  if (pres == 1) return;
  mn = inf;
  sums = pres;
  getRoot(u, 0);
  del[rt >> 1] = true;
  cnt[0] = cnt[1] = 0;
  dfs(G.e[rt].v, 0, 0, inf, false);
  dfs(G.e[rt ^ 1].v, 0, 0, inf, true);
  std::sort(path[0] + 1, path[0] + cnt[0] + 1);
  std::sort(path[1] + 1, path[1] + cnt[1] + 1);
  calc(0, G.e[rt].w);
  calc(1, G.e[rt].w);
  int currt = rt, rest = pres - siz[G.e[rt].v];
  solve(G.e[currt].v, siz[G.e[rt].v]);
  solve(G.e[currt ^ 1].v, rest);
}

int main() {
#ifndef ONLINE_JUDGE
#ifdef LOCAL
  freopen64("/tmp/CodeTmp/testdata.in", "r", stdin);
  freopen64("/tmp/CodeTmp/testdata.out", "w", stdout);
#else
  freopen("EdgeDiv.in", "r", stdin);
  freopen("EdgeDiv.out", "w", stdout);
#endif
#endif

  tot = read(n);
  for (int i = 1; i <= n; ++i) read(val[i]), ffa[i] = i;
  for (int i = 1, u, v; i < n; ++i) read(u), read(v), E.add(u, v, 1);
  build(1, 0);
  solve(1, tot);
  printf("%lld", ans);
  return 0;
}